<!-- src/components/FileUpload.vue -->
<template>
  <div class="file-upload">
    <!-- 图片上传 -->
    <div v-if="uploadType === 'image'" class="image-upload">
      <el-upload
        class="upload-demo"
        :action="uploadUrl"
        :headers="uploadHeaders"
        :data="uploadData"
        :file-list="fileList"
        :on-preview="handlePreview"
        :on-remove="handleRemove"
        :on-success="handleSuccess"
        :on-error="handleError"
        :before-upload="beforeUpload"
        :limit="limit"
        :multiple="multiple"
        :accept="accept"
        list-type="picture-card"
        :disabled="disabled"
      >
        <div class="upload-trigger">
          <el-icon class="upload-icon"><Plus /></el-icon>
          <div class="upload-text">{{ uploadText }}</div>
        </div>
      </el-upload>
      
      <!-- 图片预览对话框 -->
      <el-dialog v-model="previewVisible" title="图片预览" width="800px">
        <img :src="previewUrl" alt="预览图片" style="width: 100%; max-height: 500px; object-fit: contain;" />
      </el-dialog>
    </div>
    
    <!-- 视频上传 -->
    <div v-if="uploadType === 'video'" class="video-upload">
      <el-upload
        class="upload-demo"
        :action="uploadUrl"
        :headers="uploadHeaders"
        :data="uploadData"
        :file-list="fileList"
        :on-preview="handleVideoPreview"
        :on-remove="handleRemove"
        :on-success="handleSuccess"
        :on-error="handleError"
        :before-upload="beforeVideoUpload"
        :limit="1"
        :accept="videoAccept"
        :disabled="disabled"
      >
        <div class="video-upload-area">
          <el-icon class="video-icon"><VideoPlay /></el-icon>
          <div class="upload-text">{{ uploadText || '点击上传视频' }}</div>
          <div class="upload-hint">支持 MP4、AVI、MOV 格式，最大 {{ maxSize }}MB</div>
        </div>
        
        <template #file="{ file }">
          <div class="video-file-item">
            <el-icon class="file-icon"><VideoPlay /></el-icon>
            <div class="file-info">
              <div class="file-name">{{ file.name }}</div>
              <div class="file-size">{{ formatFileSize(file.size) }}</div>
              <div class="file-status" :class="getStatusClass(file.status)">
                {{ getStatusText(file.status) }}
              </div>
            </div>
            <div class="file-actions">
              <el-button size="small" @click="handleVideoPreview(file)">预览</el-button>
              <el-button size="small" type="danger" @click="handleRemove(file)">删除</el-button>
            </div>
          </div>
        </template>
      </el-upload>
      
      <!-- 视频预览对话框 -->
      <el-dialog v-model="videoPreviewVisible" title="视频预览" width="800px">
        <video 
          v-if="videoPreviewUrl" 
          :src="videoPreviewUrl" 
          controls 
          style="width: 100%; max-height: 400px;"
        >
          您的浏览器不支持视频播放
        </video>
      </el-dialog>
    </div>
    
    <!-- 文件上传 -->
    <div v-if="uploadType === 'file'" class="file-upload-area">
      <el-upload
        class="upload-demo"
        :action="uploadUrl"
        :headers="uploadHeaders"
        :data="uploadData"
        :file-list="fileList"
        :on-remove="handleRemove"
        :on-success="handleSuccess"
        :on-error="handleError"
        :before-upload="beforeFileUpload"
        :limit="limit"
        :accept="accept"
        :disabled="disabled"
      >
        <div class="file-upload-trigger">
          <el-icon class="file-icon"><Document /></el-icon>
          <div class="upload-text">{{ uploadText || '点击上传文件' }}</div>
          <div class="upload-hint">{{ acceptHint }}</div>
        </div>
      </el-upload>
    </div>
  </div>
</template>

<script>
import { ref, computed, watch } from 'vue'
import { ElMessage } from 'element-plus'
import { Plus, VideoPlay, Document } from '@element-plus/icons-vue'

export default {
  name: 'FileUpload',
  props: {
    // 上传类型：image, video, file
    uploadType: {
      type: String,
      default: 'image'
    },
    // 上传地址
    uploadUrl: {
      type: String,
      default: '/api/upload'
    },
    // 文件列表
    modelValue: {
      type: Array,
      default: () => []
    },
    // 最大上传数量
    limit: {
      type: Number,
      default: 1
    },
    // 是否支持多选
    multiple: {
      type: Boolean,
      default: false
    },
    // 文件大小限制（MB）
    maxSize: {
      type: Number,
      default: 5
    },
    // 上传提示文字
    uploadText: {
      type: String,
      default: ''
    },
    // 是否禁用
    disabled: {
      type: Boolean,
      default: false
    },
    // 额外的上传参数
    uploadData: {
      type: Object,
      default: () => ({})
    }
  },
  emits: ['update:modelValue', 'success', 'error', 'remove'],
  setup(props, { emit }) {
    const fileList = ref(props.modelValue || [])
    const previewVisible = ref(false)
    const previewUrl = ref('')
    const videoPreviewVisible = ref(false)
    const videoPreviewUrl = ref('')
    
    // 上传请求头
    const uploadHeaders = computed(() => {
      const token = localStorage.getItem('token')
      return token ? { Authorization: `Bearer ${token}` } : {}
    })
    
    // 图片文件接受类型
    const accept = computed(() => {
      if (props.uploadType === 'image') {
        return 'image/jpeg,image/jpg,image/png,image/gif,image/webp'
      } else if (props.uploadType === 'file') {
        return '.pdf,.doc,.docx,.xls,.xlsx,.txt'
      }
      return '*'
    })
    
    // 视频文件接受类型
    const videoAccept = 'video/mp4,video/avi,video/mov,video/wmv'
    
    // 文件类型提示
    const acceptHint = computed(() => {
      if (props.uploadType === 'image') {
        return '支持 JPG、PNG、GIF 格式'
      } else if (props.uploadType === 'video') {
        return '支持 MP4、AVI、MOV 格式'
      } else if (props.uploadType === 'file') {
        return '支持 PDF、Word、Excel、TXT 格式'
      }
      return ''
    })
    
    // 监听文件列表变化
    watch(() => props.modelValue, (newVal) => {
      fileList.value = newVal || []
    }, { deep: true })
    
    // 图片预览
    const handlePreview = (file) => {
      previewUrl.value = file.url || file.response?.data?.url
      previewVisible.value = true
    }
    
    // 视频预览
    const handleVideoPreview = (file) => {
      videoPreviewUrl.value = file.url || file.response?.data?.url
      videoPreviewVisible.value = true
    }
    
    // 文件移除
    const handleRemove = (file) => {
      const index = fileList.value.findIndex(item => item.uid === file.uid)
      if (index !== -1) {
        fileList.value.splice(index, 1)
        emit('update:modelValue', fileList.value)
        emit('remove', file)
      }
    }
    
    // 上传成功
    const handleSuccess = (response, file) => {
      if (response.success || response.code === 200) {
        file.url = response.data?.url || response.url
        emit('update:modelValue', fileList.value)
        emit('success', response.data || response, file)
        ElMessage.success('文件上传成功')
      } else {
        handleError(response.message || '上传失败', file)
      }
    }
    
    // 上传失败
    const handleError = (error, file) => {
      ElMessage.error(typeof error === 'string' ? error : '上传失败，请重试')
      emit('error', error, file)
      
      // 从文件列表中移除失败的文件
      const index = fileList.value.findIndex(item => item.uid === file.uid)
      if (index !== -1) {
        fileList.value.splice(index, 1)
      }
    }
    
    // 图片上传前检查
    const beforeUpload = (file) => {
      // 检查文件类型
      const isImage = file.type.startsWith('image/')
      if (!isImage) {
        ElMessage.error('只能上传图片文件')
        return false
      }
      
      // 检查文件大小
      const isLimitSize = file.size / 1024 / 1024 < props.maxSize
      if (!isLimitSize) {
        ElMessage.error(`图片大小不能超过 ${props.maxSize}MB`)
        return false
      }
      
      return true
    }
    
    // 视频上传前检查
    const beforeVideoUpload = (file) => {
      // 检查文件类型
      const isVideo = file.type.startsWith('video/')
      if (!isVideo) {
        ElMessage.error('只能上传视频文件')
        return false
      }
      
      // 检查文件大小
      const maxVideoSize = props.maxSize || 100 // 视频默认100MB
      const isLimitSize = file.size / 1024 / 1024 < maxVideoSize
      if (!isLimitSize) {
        ElMessage.error(`视频大小不能超过 ${maxVideoSize}MB`)
        return false
      }
      
      return true
    }
    
    // 文件上传前检查
    const beforeFileUpload = (file) => {
      // 检查文件大小
      const isLimitSize = file.size / 1024 / 1024 < props.maxSize
      if (!isLimitSize) {
        ElMessage.error(`文件大小不能超过 ${props.maxSize}MB`)
        return false
      }
      
      return true
    }
    
    // 格式化文件大小
    const formatFileSize = (bytes) => {
      if (bytes === 0) return '0 Bytes'
      const k = 1024
      const sizes = ['Bytes', 'KB', 'MB', 'GB']
      const i = Math.floor(Math.log(bytes) / Math.log(k))
      return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
    }
    
    // 获取文件状态样式
    const getStatusClass = (status) => {
      return {
        'status-success': status === 'success',
        'status-uploading': status === 'uploading',
        'status-error': status === 'error'
      }
    }
    
    // 获取状态文本
    const getStatusText = (status) => {
      const statusMap = {
        ready: '准备上传',
        uploading: '上传中...',
        success: '上传成功',
        error: '上传失败'
      }
      return statusMap[status] || status
    }
    
    return {
      fileList,
      previewVisible,
      previewUrl,
      videoPreviewVisible,
      videoPreviewUrl,
      uploadHeaders,
      accept,
      videoAccept,
      acceptHint,
      handlePreview,
      handleVideoPreview,
      handleRemove,
      handleSuccess,
      handleError,
      beforeUpload,
      beforeVideoUpload,
      beforeFileUpload,
      formatFileSize,
      getStatusClass,
      getStatusText,
      Plus,
      VideoPlay,
      Document
    }
  }
}
</script>

<style scoped>
.file-upload {
  width: 100%;
}

/* 图片上传 */
.image-upload {
  .upload-demo {
    :deep(.el-upload--picture-card) {
      width: 120px;
      height: 120px;
      border-radius: 8px;
      border: 2px dashed #ddd;
      transition: all 0.3s;
      
      &:hover {
        border-color: #409eff;
      }
    }
    
    :deep(.el-upload-list--picture-card .el-upload-list__item) {
      width: 120px;
      height: 120px;
      border-radius: 8px;
    }
  }
  
  .upload-trigger {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    height: 100%;
    
    .upload-icon {
      font-size: 28px;
      color: #8c939d;
      margin-bottom: 8px;
    }
    
    .upload-text {
      font-size: 14px;
      color: #8c939d;
    }
  }
}

/* 视频上传 */
.video-upload {
  .video-upload-area {
    border: 2px dashed #ddd;
    border-radius: 8px;
    padding: 40px;
    text-align: center;
    transition: all 0.3s;
    cursor: pointer;
    
    &:hover {
      border-color: #409eff;
    }
    
    .video-icon {
      font-size: 48px;
      color: #8c939d;
      margin-bottom: 16px;
    }
    
    .upload-text {
      font-size: 16px;
      color: #606266;
      margin-bottom: 8px;
    }
    
    .upload-hint {
      font-size: 12px;
      color: #909399;
    }
  }
  
  .video-file-item {
    display: flex;
    align-items: center;
    padding: 12px;
    border: 1px solid #ebeef5;
    border-radius: 6px;
    margin-top: 8px;
    
    .file-icon {
      font-size: 24px;
      color: #409eff;
      margin-right: 12px;
    }
    
    .file-info {
      flex: 1;
      
      .file-name {
        font-size: 14px;
        color: #606266;
        margin-bottom: 4px;
      }
      
      .file-size {
        font-size: 12px;
        color: #909399;
        margin-bottom: 4px;
      }
      
      .file-status {
        font-size: 12px;
        
        &.status-success {
          color: #67c23a;
        }
        
        &.status-uploading {
          color: #409eff;
        }
        
        &.status-error {
          color: #f56c6c;
        }
      }
    }
    
    .file-actions {
      display: flex;
      gap: 8px;
    }
  }
}

/* 文件上传 */
.file-upload-area {
  .file-upload-trigger {
    border: 2px dashed #ddd;
    border-radius: 8px;
    padding: 40px;
    text-align: center;
    transition: all 0.3s;
    cursor: pointer;
    
    &:hover {
      border-color: #409eff;
    }
    
    .file-icon {
      font-size: 48px;
      color: #8c939d;
      margin-bottom: 16px;
    }
    
    .upload-text {
      font-size: 16px;
      color: #606266;
      margin-bottom: 8px;
    }
    
    .upload-hint {
      font-size: 12px;
      color: #909399;
    }
  }
}
</style>